<template>
	<!-- 生产日报表 -->
	<div class="content">
		<div class="pageSearchView">
			<el-form :inline="true" :model="searchParam" class="demo-form-inline" :rules="formRules" ref="searchForm">
				<el-form-item label="物料" style="width: 250px" prop="materalId">
					<el-select v-model="searchParam.productCode" remote :remote-method="remoteMethod" filterable clearable
										 placeholder="请选择物料">
						<el-option v-for="(item, index) of materialList" :key="index" :label="item.productName" :value="item.productCode" />
					</el-select>
				</el-form-item>
				<el-form-item label="年份" prop="year">
					<el-date-picker v-model="searchParam.year" type="year" value-format="YYYY" placeholder="请选择年份" />
				</el-form-item>
				<el-form-item label="开始周次" prop="startWeek">
					<el-date-picker v-model="searchParam.startWeek" type="week" format="[第] ww [周]" value-format="ww"
													placeholder="选择开始周次" />
				</el-form-item>
				<el-form-item label="结束周次" prop="endWeek">
					<el-date-picker v-model="searchParam.endWeek" type="week" format="[第] ww [周]" value-format="ww"
													placeholder="选择结束周次" />
				</el-form-item>
				<el-form-item>
					<el-button type="primary" :icon="Search" @click="submitForm()">查询</el-button>
					<el-button class="refreshBtn" :icon="Refresh" @click="resetSearch()">重置</el-button>
				</el-form-item>
			</el-form>
		</div>
		<div class="pageTableView">
			<div class="pageTableMenuView">
				<div class="pageTableTitle">列表信息</div>
				<div class="pageTableButView">
					<el-upload class="upload-demo" :headers="uploadHeaders" action="/api/rawMaterialShortage/upload-parse"
										 :show-file-list="false"
										 :on-success="handleSuccess" :on-error="handleError" :on-progress="handleProgress">
						<el-button icon="Plus" :loading="importLoading" type="primary">导入</el-button>
					</el-upload>
					<el-button icon="Download" type="primary" :loading="downLoading" @click="handleExport"
										 style="margin-left: 10px;">导出
					</el-button>
					<el-button icon="Download" type="primary"
										 style="margin-left: 10px;">
						<a :href="baseUrl+':9012/download/rawTemplatel.xlsx'"> 模板下载 </a>
					</el-button>
				</div>
			</div>
			<!-- 表格 -->
			<el-table :data="paginatedData" :span-method="arraySpanMethod" border style="width: 100%"
								height="calc(100vh - 290px)">
				<!--				<el-table-column type="index" width="60" align="center"></el-table-column>-->
				<el-table-column prop="productCode" label="产品编码" min-width="180" align="center"></el-table-column>
				<el-table-column prop="parameterName" label="参数" min-width="180" align="center"></el-table-column>
				<el-table-column
					v-for="week in dateList"
					:key="week"
					:label="'第 ' + week + ' 周'"
					min-width="180" align="center">
					<template #default="scope">
						{{ scope.row.weeksData[week] || 0 }}
					</template>
				</el-table-column>
			</el-table>
			<div class="pagePagination">
				<el-pagination background v-model:current-page="pageSearch.current" v-model:page-size="pageSearch.pageSize"
											 :page-sizes="[10, 20, 50, 100, 200, 500]" layout="total, sizes, prev, pager, next"
											 :total="pageTotal"
											 @size-change="handleSizeChange" @current-change="handleCurrentChange" />
			</div>
		</div>
	</div>
</template>
<script lang="ts" setup>
import { computed, reactive, ref, onMounted } from 'vue';
import { ElMessage, ElForm } from 'element-plus';
import { ElMessageBox } from 'element-plus';
import axiosInstance from '@/utils/http/api';
import { Delete, Edit, Plus, Refresh, Search, Download } from '@element-plus/icons-vue';
import dayjs from 'dayjs';

const searchForm = ref<InstanceType<typeof ElForm>>();
const importLoading = ref(false);
const pageSearch = ref({
	current: 1,
	pageSize: 99999999
});

const uploadHeaders = ref({
		'bearertoken': localStorage.getItem('token')
	}
);

const pageTotal = ref(null); // 页面总数
const searchParam = ref({
	year: new Date().getFullYear().toString()
});

const materialList = ref([]); // 物料表
const processData = ref([]); // 工序

const formRules = ref({
	// procedureIds: [{ required: true, message: '请选择工序', trigger: 'change' }],
	// startWeek: [{ required: true, message: '请选择开始周次', trigger: 'change' }],
	// endWeek: [{ required: true, message: '请选择结束周次', trigger: 'change' }],
	// year: [{ required: true, message: '请选择年份', trigger: 'change' }]
});
const fileList = ref([]);
const handleProgress = () => {
	importLoading.value = true;
};
const handleSuccess = (response, file, fileList) => {
	if (response.code === 200) {
		importLoading.value = false;
		axiosInstance.post('/api/rawMaterialShortage/saveBatch', response.data)
			.then(res => {
				if (res.code !== 200) {
					ElMessage.error(res.message);
					return false;
				}
				ElMessage.success('批量报存成功');
				// searchParam.value = {};
				submitForm();
			});
		// 处理上传成功后的逻辑，比如刷新列表等
	} else {
		importLoading.value = false;
		ElMessage.error(response.message || '文件上传失败');
	}
};

const handleError = () => {
	console.log(11111);
	importLoading.value = false;
	ElMessage.error('文件上传失败');
};


const getSpanArr = (data) => {
	let spanArr = [];
	let spanArr1 = [];
	let pos = 0;
	let pos1 = 0;

	for (let i = 0; i < data.length; i++) {
		if (i === 0) {
			spanArr.push(1);
			spanArr1.push(1);
			pos = 0;
			pos1 = 0;
		} else {
			// 检查物料名称是否相同
			if (data[i].productId === data[i - 1].productId) {
				spanArr[pos] += 1;
				spanArr.push(0);
				// 检查工序名称是否相同
			} else {
				spanArr.push(1);
				spanArr1.push(1);
				pos = i;
				pos1 = i;
			}
		}
	}
	return [spanArr, spanArr1];
};

const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
	// 获取合并信息数组
	const [spanArr, spanArr1] = getSpanArr(paginatedData.value);

	if (columnIndex === 0) { // 物料列
		const _row = spanArr[rowIndex];
		const _col = _row > 0 ? 1 : 0;
		return {
			rowspan: _row,
			colspan: _col
		};
	}
	//  else if (columnIndex === 2) { // 工序名称列
	//   const _row = spanArr1[rowIndex];
	//   const _col = _row > 0 ? 1 : 0;
	//   return {
	//     rowspan: _row,
	//     colspan: _col
	//   };
	// }
};


const paginatedData = ref([]);
const workRoomList = ref([]); // 车间

const getOption = () => {
	axiosInstance.post('/api/basedataOrganization/getAll', {})
		.then(res => {
			if (res.code !== 200) {
				ElMessage.error(res.message);
				return false;
			}
			workRoomList.value = res.data;
		});
	axiosInstance.post('/api/basedataProduct/getPage', {
		current: 1, pageSize: 50
	})
		.then(res => {
			if (res.code !== 200) {
				ElMessage.error(res.message);
				return false;
			}
			materialList.value = res.data.records;
		});
};

const remoteMethod = (value) => {
	console.log(value);

	if (!value) {
		return;
	}
	axiosInstance.post('/api/basedataProduct/getPage', {
		current: 1, pageSize: 50, productName: value
	})
		.then(res => {
			if (res.code !== 200) {
				ElMessage.error(res.message);
				return false;
			}
			materialList.value = res.data.records;
		});
};

import axios from 'axios';
import moment from 'moment';

const downLoading = ref(false);

const apiPost = import.meta.env.VITE_API_PROXY_TARGET;

const handleExport = () => {
	if (searchParam.value.startWeek > searchParam.value.endWeek) {
		ElMessage.error('开始周次不能大于结束周次');
		return false;
	}

	// if (searchParam.value.materalId) {
	// 	const materalName = materialList.value.find(item => item.id === searchParam.value.materalId).productName;
	// }

	downLoading.value = true;
	axios.post('/api/rawMaterialShortage/exportExcel', {
		...searchParam.value,
		...pageSearch.value

	}, {
		timeout: 30000, // 与 axiosInstance 的 timeout 相同
		responseType: 'blob',
		headers: {
			BearerToken: localStorage.getItem('token') || undefined // 与请求拦截器中的设置相同
		}
	})
		.then(response => {
			console.log(response);
			const url = window.URL.createObjectURL(new Blob([response.data]));
			const link = document.createElement('a');
			link.href = url;
			const formattedDate = moment().format('YYYYMMDD');
			link.setAttribute('download', '原材料需求统计' + formattedDate + '.xlsx'); // 导出的格式一定要和接口返回的文件一致
			document.body.appendChild(link);
			link.click();
			window.URL.revokeObjectURL(url);
			document.body.removeChild(link);
		})
		.finally(() => {
			downLoading.value = false;
		});
};

const dateList = ref([]);
const getList = () => {
	if (searchParam.value.startWeek > searchParam.value.endWeek) {
		ElMessage.error('开始周次不能大于结束周次');
		return false;
	}

	axiosInstance.post('/api/rawMaterialShortage/getPage', {
		...searchParam.value,
		...pageSearch.value
	})
		.then(res => {
			if (res.code !== 200) {
				ElMessage.error(res.message);
				return false;
			}

			if (res.data.records.length === 0) {
				paginatedData.value = [];
				return;
			}

			// 获取所有唯一的productId
			const productIds = [...new Set(res.data.records.map(item => item.productId))];
			dateList.value = [...new Set(res.data.records.map(item => item.week))].sort((a, b) => a - b);
			// 获取所有唯一的week
			const uniqueWeeks = [...new Set(res.data.records.map(item => item.week))].sort();

			// 初始化结果数组
			const result = [];

			// 定义参数名称及其对应的字段名
			const parameterMap = {
				'计划数量': 'planCount',
				'成品数量': 'finishedProductCount',
				'在制品数量': 'articlesProcessCount',
				'缺少成品数量': 'lackFinishedProductCount',
				'原材料数量': 'rawMaterialCount',
				'在途原材料数量': 'wayRawMaterialCount',
				'缺少原材料数量': 'lackRawMaterialCount'
			};

			// 遍历每个productId
			productIds.forEach(productId => {
				// 遍历每个参数，为每个参数生成一条数据
				Object.keys(parameterMap).forEach(parameterName => {
					// 创建一个新对象来存储数据
					const newRow = {
						productId: productId,
						parameterName: parameterName,
						productCode: '', // 初始化产品编码，后续根据实际数据填充
						weeksData: {} // 初始化周次数据，后续根据实际数据填充
					};

					// 为每个week填充数据
					uniqueWeeks.forEach(week => {
						// 查找对应productId和week的数据记录
						const record = res.data.records.find(r => r.productId === productId && r.week === week);
						console.log(record, 'record');
						if (record) {
							// 设置产品编码
							newRow.productCode = record.productCode;
							// 检查是否需要拼接finishedProductBasicUnit字段
							let value = record[parameterMap[parameterName]];
							if (['计划数量', '成品数量', '在制品数量', '缺少成品数量'].includes(parameterName)) {
								value = `${value} ${record.finishedProductBasicUnit || ''}`;
							}
							if (['原材料数量', '在途原材料数量', '缺少原材料数量'].includes(parameterName)) {
								value = `${value} ${record.rawMaterialBasicUnit || ''}`;
							}
							// 设置对应参数的数据
							newRow.weeksData[week] = value;
						} else {
							// 如果没有对应的数据，则设置为0或其他默认值
							newRow.weeksData[week] = 0;
						}
					});

					// 将新行添加到结果数组中
					result.push(newRow);
				});
			});

			// 更新表格数据
			paginatedData.value = result;
			console.log(result);
		});
};


const handleSizeChange = (e) => {
	pageSearch.value.pageSize = e;
	getList();
};

const handleCurrentChange = (e) => {
	pageSearch.value.current = e;
	getList();
};

// 提交表单
const submitForm = () => {
	searchForm.value?.validate((valid) => {
		if (valid) {
			getList();
		}
	});
};

// 重置搜索条件
const resetSearch = () => {
	searchParam.value = {
		year: new Date().getFullYear().toString()
	};
	pageSearch.value.current = 1;
	getList();
};


const initializeWeeks = () => {
	const currentYear = dayjs().year();
	const currentWeek = dayjs().week();
	const endWeek = currentWeek + 6;
	searchParam.value.startWeek = currentWeek.toString();
	const firstDay = new Date(currentYear, 0, 1);
	const lastDay = new Date(currentYear, 11, 31);

	const firstDayOfWeek = firstDay.getDay();
	let daysInYear = (lastDay - firstDay) / (1000 * 60 * 60 * 24) + 1;

	// 根据ISO 8601标准，一周从周一开始，周日结束，如果第一天是周一，则总天数加一
	if (firstDayOfWeek === 1) {
		daysInYear += 1;
	}

	// 将总天数除以7，取整可得一年中的周数
	const weeksInYear = Math.ceil(daysInYear / 7);
	if (endWeek > weeksInYear) {
		searchParam.value.endWeek = (weeksInYear - 1).toString();
	} else {
		searchParam.value.endWeek = (endWeek - 1).toString();
	}
	submitForm();
};

// ... 其他代码
const { protocol, hostname } = window.location;
const baseUrl = ref('');
baseUrl.value = `${protocol}//${hostname}`;
console.log(baseUrl, 'baseUrlbaseUrl');
onMounted(() => {
	// getList();
	getOption();
	initializeWeeks();
});
</script>
<style scoped></style>